// b20.v
// Verilog version, rewritten by Li Shen, Aug 2002
// Institute of Computing Technology, Chinese Academy of Sciences
// The original VHDL version is b20.vhd from Politecnico di Torino

module b14 (clock, reset, datai, rd, wr, addr, datao);
input clock;
input reset;
input [31:0] datai; //signed
output rd;
output wr;
output [19:0] addr;
output [31:0] datao; //signed
//////
wire clock;
wire reset;
wire [31:0] datai; //signed
reg rd;
reg wr;
reg [19:0] addr;
reg [31:0] datao; //signed
/////
reg [31:0] reg0; //signed
reg [31:0] reg1; //signed
reg [31:0] reg2; //signed
reg [31:0] reg3; //signed
reg B;
reg [19:0] MAR;
reg [31:0] MBR; //signed
reg [1:0] mf;
reg [2:0] df;
reg cf;
reg [3:0] ff;
reg [19:0] tail;
reg [31:0] IR; //signed
reg state;
reg [31:0] r,m,t; //signed
reg [31:0] d; //signed
reg [31:0] temp; //signed
reg [1:0] s;
reg [32:0] a; //signed
parameter FETCH=0, EXEC=1;
/////
always @(posedge clock)
begin
  if (reset)
  begin
      MAR = 0;
      MBR = 0;
      IR = 0;
      d = 0;
      r = 0;
      m = 0;
      s = 0;
      temp = 0;
      mf = 0;
      df = 0;
      ff = 0;
      cf = 0;
      tail = 0;
      B = 0;
      reg0 = 0;
      reg1 = 0;
      reg2 = 0;
      reg3 = 0;
      addr <= 0;
      rd <= 0;
      wr <= 0;
      datao <= 0;
      state = FETCH;
  end
  else
  begin
      rd <= 0;
      wr <= 0;
      case (state)
      FETCH:
      begin
        MAR = reg3 & 20'hfffff;
	addr <= MAR;
	rd <= 1;
	MBR = datai;
        IR = MBR;
	state = EXEC;
      end
      EXEC:
      begin
	if (IR[31]) //<0
	  IR = -IR;
	mf = (IR >> 27) & 3 ;
	df = (IR >> 24) & 7;
	ff = (IR >> 19) & 15;
	cf = (IR >> 23) & 1;
	tail = IR & 20'hfffff;
        reg3 = ((reg3 & 32'h1fffffff)+ 8);
	s = (IR >> 29) & 3;
	case (s)
	0: r = reg0;
	1: r = reg1;
	2: r = reg2;
	3: r = reg3;
	endcase
	case (cf)
	1:
        begin
	  case (mf)
	  0:   m = tail;
	  1: begin
               m = datai;
	       addr <= tail;
	       rd <= 1;
             end
	  2: begin
               addr <= (tail + reg1) & 20'hfffff;
	       rd <= 1;
               m = datai;
             end
	  3: begin
               addr <= (tail + reg2) & 20'hfffff;
	       rd <= 1;
               m = datai;
             end
	  endcase
	  case (ff)
	  0: begin
	       a = {r[31],r} - {m[31],m};
	       if (a[32]) B = 1; //r<m
               else	  B = 0;
	     end
	  1: begin
	       a = {r[31],r} - {m[31],m};
	       if (!a[32]) B = 1; //not(r<m)
               else	   B = 0;
	     end
	  2: if (r == m) B = 1;
             else	  B = 0; 
	  3: if (r != m) B = 1;
             else	  B = 0; 
	  4: begin
	       a = {m[31],m} - {r[31],r};
	       if (!a[32]) B = 1; //not(m<r)
               else	   B = 0;
	     end
	  5: begin
	       a = {m[31],m} - {r[31],r};
	       if (a[32]) B = 1; //m<r
               else	  B = 0;
	     end
	  6: begin
	       if (!r[31] && r>32'h3fffffff) r = r - 32'h40000000;
	       a = {r[31],r} - {m[31],m};
	       if (a[32]) B = 1; //r<m
               else	  B = 0;
	     end 
	  7: begin
	       if (!r[31] && r>32'h3fffffff) r = r - 32'h40000000;
	       a = {r[31],r} - {m[31],m};
	       if (!a[32]) B = 1; //not(r<m)
               else	   B = 0;
	     end 
	  8: begin
	       a = {r[31],r} - {m[31],m};
	       if (a[32] || B) B = 1; //r<m
               else	       B = 0;
	     end 
	  9: begin
	       a = {r[31],r} - {m[31],m};
	       if (!a[32] || B) B = 1; //not(r<m)
               else	        B = 0;
	     end 
	  10: if (r == m || B) B = 1;
              else		B = 0;
	  11: if (r != m || B) B = 1;
              else	 	   B = 0;
	  12: begin
	        a = {m[31],m} - {r[31],r};
	        if (!a[32] || B) B = 1; //not(m<r)
                else	         B = 0;
	      end
	  13: begin
	        a = {m[31],m} - {r[31],r};
	        if (a[32] || B) B = 1; //m<r
                else	        B = 0;
	      end
	  14: begin
	       if (!r[31] && r>32'h3fffffff) r = r - 32'h40000000;
	       a = {r[31],r} - {m[31],m};
	       if (a[32] || B) B = 1; //r<m
               else	       B = 0;
	      end 
	  15: begin
	       if (!r[31] && r>32'h3fffffff) r = r - 32'h40000000;
	       a = {r[31],r} - {m[31],m};
	       if (!a[32] || B) B = 1; //not(r<m)
               else	        B = 0;
	      end 
	  endcase
	end
	0:
	begin
	  if (df != 7)
	  begin
	    if (df == 5)
	    begin
	         if (!B) d = 3;
	    end
	    else if (df == 4)
	    begin
	         if (B) d = 3;
	    end
	    else if (df == 3) d = 3;
	    else if (df == 2) d = 2;
	    else if (df == 1) d = 1;
	    else if (df == 0) d = 0;

	    case (ff)
	    0:
	    begin
	      case (mf)
	      0:   m = tail;
	      1: begin
		   m = datai;
		   addr <= tail;
		   rd <= 1;
		 end
	      2: begin
		  addr <= (tail + reg1) & 20'hfffff;
		  rd <= 1;
                  m = datai;
		 end
	      3: begin
		  addr <= (tail + reg2) & 20'hfffff;
		  rd <= 1;
                  m = datai;
		 end
	      endcase
	      t = 0;
	      case (d)
	      0: reg0 = t - m;
	      1: reg1 = t - m;
	      2: reg2 = t - m;
	      3: reg3 = t - m;
	      endcase
	    end
	    1:
	    begin
	      case (mf)
	      0:   m = tail;
	      1: begin
		   m = datai;
		   addr <= tail;
		   rd <= 1;
		 end
	      2: begin
		   addr <= (tail + reg1) & 20'hfffff;
		   rd <= 1;
                   m = datai;
		 end
	      3: begin
		   addr <= (tail + reg2) & 20'hfffff;
		   rd <= 1;
                   m = datai;
		 end
	      endcase
	      reg2 = reg3; 
	      reg3 = m;
	    end
	    2:
	    begin
	      case (mf)
	      0:   m = tail;
	      1: begin
		   m = datai;
		   addr <= tail;
		   rd <= 1;
		 end
	      2: begin
		   addr <= (tail + reg1) & 20'hfffff;
		   rd <= 1;
                   m = datai;
		 end
	      3: begin
		   addr <= (tail + reg2) & 20'hfffff;
		   rd <= 1;
                   m = datai;
		 end
	      endcase
	      case (d)
	      0: reg0 = m;
	      1: reg1 = m;
	      2: reg2 = m;
	      3: reg3 = m;
	      endcase
	    end
	    3:
	    begin 
	      case (mf)
	      0:  m = tail;
	      1: begin
		  m = datai;
		  addr <= tail;
		  rd <= 1;
		 end
	      2: begin
		   addr <= (tail + reg1) & 20'hfffff;
		   rd <= 1;
                   m = datai;
		 end
	      3: begin
		   addr <= (tail + reg2) & 20'hfffff;
		   rd <= 1;
                   m = datai;
		 end
	      endcase
	      case (d)
	      0: reg0 = m;
	      1: reg1 = m;
	      2: reg2 = m;
	      3: reg3 = m;
	      endcase
	    end
	    4:
	    begin
	      case (mf)
	      0: m = tail;
	      1: begin
		   m = datai;
		   addr <= tail;
		   rd <= 1;
		 end
	      2: begin
		   addr <= (tail + reg1) & 20'hfffff;
		   rd <= 1;
                   m = datai;
		 end
	      3: begin
		   addr <= (tail + reg2) & 20'hfffff;
		   rd <= 1;
                   m = datai;
		 end
	      endcase
	      case (d)
	      0: reg0 = (r + m) & 32'h3fffffff;
	      1: reg1 = (r + m) & 32'h3fffffff;
	      2: reg2 = (r + m) & 32'h3fffffff;
	      3: reg3 = (r + m) & 32'h3fffffff;
	      endcase
	    end
	    5:
	    begin
	      case (mf)
	      0:   m = tail;
	      1: begin
		   m = datai;
		   addr <= tail;
		   rd <= 1;
		 end
	      2: begin
		   addr <= (tail + reg1) & 20'hfffff;
		   rd <= 1;
                   m = datai;
		 end
	      3: begin
		   addr <= (tail + reg2) & 20'hfffff;
		   rd <= 1;
                   m = datai;
		 end
	      endcase
	      case (d)
	      0: reg0 = (r + m) & 32'h3fffffff;
	      1: reg1 = (r + m) & 32'h3fffffff;
	      2: reg2 = (r + m) & 32'h3fffffff;
	      3: reg3 = (r + m) & 32'h3fffffff;
	      endcase
	    end
	    6:
	    begin
	      case (mf)
	      0:   m = tail;
	      1: begin
		   m = datai;
		   addr <= tail;
		   rd <= 1;
		 end
	      2: begin
		   addr <= (tail + reg1) & 20'hfffff;
		   rd <= 1;
                   m = datai;
		 end
	      3: begin
		   addr <= (tail + reg2) & 20'hfffff;
		   rd <= 1;
                   m = datai;
		 end
	      endcase
	      case (d)
	      0: reg0 = (r - m) & 32'h3fffffff;
	      1: reg1 = (r - m) & 32'h3fffffff;
	      2: reg2 = (r - m) & 32'h3fffffff;
	      3: reg3 = (r - m) & 32'h3fffffff;
	      endcase
	    end
	    7:
	    begin
	      case (mf)
	      0:   m = tail;
	      1: begin
		   m = datai;
		   addr <= tail;
		   rd <= 1;
		 end
	      2: begin
		   addr <= (tail + reg1) & 20'hfffff;
		   rd <= 1;
                   m = datai;
		 end
	      3: begin
		   addr <= (tail + reg2) & 20'hfffff;
		   rd <= 1;
                   m = datai;
		 end
	      endcase
	      case (d)
	      0: reg0 = (r - m) & 32'h3fffffff;
	      1: reg1 = (r - m) & 32'h3fffffff;
	      2: reg2 = (r - m) & 32'h3fffffff;
	      3: reg3 = (r - m) & 32'h3fffffff;
	      endcase
	    end
	    8:
	    begin
	      case (mf)
	      0:   m = tail;
	      1: begin
		   m = datai;
		   addr <= tail;
		   rd <= 1;
		 end
	      2: begin
		   addr <= (tail + reg1) & 20'hfffff;
		   rd <= 1;
                   m = datai;
		 end
	      3: begin
		   addr <= (tail + reg2) & 20'hfffff;
		   rd <= 1;
                   m = datai;
		 end
	      endcase
	      case (d)
	      0: reg0 = (r + m) & 32'h3fffffff;
	      1: reg1 = (r + m) & 32'h3fffffff;
	      2: reg2 = (r + m) & 32'h3fffffff;
	      3: reg3 = (r + m) & 32'h3fffffff;
	      endcase
	    end
	    9:
	    begin
	      case (mf)
	      0:   m = tail;
	      1: begin
		   m = datai;
		   addr <= tail;
		   rd <= 1;
		 end
	      2: begin
		   addr <= (tail + reg1) & 20'hfffff;
		   rd <= 1;
                   m = datai;
		 end
	      3: begin
		   addr <= (tail + reg2) & 20'hfffff;
		   rd <= 1;
                   m = datai;
		 end
	      endcase
	      case (d)
	      0: reg0 = (r - m) & 32'h3fffffff;
	      1: reg1 = (r - m) & 32'h3fffffff;
	      2: reg2 = (r - m) & 32'h3fffffff;
	      3: reg3 = (r - m) & 32'h3fffffff;
	      endcase
	    end
	    10: 
	    begin
	      case (mf)
	      0:   m = tail;
	      1: begin
		   m = datai;
		   addr <= tail;
		   rd <= 1;
		 end
	      2: begin
		   addr <= (tail + reg1) & 20'hfffff;
		   rd <= 1;
                   m = datai;
		 end
	      3: begin
		   addr <= (tail + reg2) & 20'hfffff;
		   rd <= 1;
                   m = datai;
		 end
	      endcase
	      case (d)
	      0: reg0 = (r + m) & 32'h3fffffff;
	      1: reg1 = (r + m) & 32'h3fffffff;
	      2: reg2 = (r + m) & 32'h3fffffff;
	      3: reg3 = (r + m) & 32'h3fffffff;
	      endcase
	    end
	    11:
	    begin
	      case (mf)
	      0:   m = tail;
	      1: begin
		   m = datai;
		   addr <= tail;
		   rd <= 1;
		 end
	      2: begin
		   addr <= (tail + reg1) & 20'hfffff;
		   rd <= 1;
                   m = datai;
		 end
	      3: begin
		   addr <= (tail + reg2) & 20'hfffff;
		   rd <= 1;
                   m = datai;
		 end
	      endcase
	      case (d)
	      0: reg0 = (r - m) & 32'h3fffffff;
	      1: reg1 = (r - m) & 32'h3fffffff;
	      2: reg2 = (r - m) & 32'h3fffffff;
	      3: reg3 = (r - m) & 32'h3fffffff;
	      endcase
	    end
	    12:
	    begin
	      case (mf)
	      0:   if (r[31]) t = -(-r >> 1);
		   else       t = r >> 1;
              1: begin
		   if (r[31]) t = -(-r >> 1);
		   else       t = r >> 1;
		   if (B) t = t & 32'h1fffffff;
		 end
	      2: t = (r & 32'h1fffffff) << 1;
	      3: begin
		   t = (r & 32'h1fffffff) << 1;
		   if (!t[31] && t > 32'h3fffffff) B = 1;
		   else			           B = 0;
		 end
	      endcase
	      case (d)
	      0: reg0 = t;
	      1: reg1 = t;
	      2: reg2 = t;
	      3: reg3 = t;
	      endcase
	    end
	    endcase
	  end
	  else
	  begin
	    if (df == 7)
	    begin
	      case (mf)
	      0: m = tail;
	      1: m = tail;
	      2: m = (reg1 & 20'hfffff) + (tail & 20'hfffff);
	      3: m = (reg2 & 20'hfffff) + (tail & 20'hfffff);
	      endcase
	      addr <= m & 20'hfffff;
	      wr <=1;
	      datao <= r;
	    end
	  end
	end
	endcase
	state = FETCH;
      end
      endcase
  end
end
endmodule

//////////

module b14rev (clock, reset, datai, rd, wr, addr, datao);
input clock;
input reset;
input [31:0] datai; //signed
output rd;
output wr;
output [19:0] addr;
output [31:0] datao; //signed
//////
wire clock;
wire reset;
wire [31:0] datai; //signed
reg rd;
reg wr;
reg [19:0] addr;
reg [31:0] datao; //signed
/////
reg [31:0] reg0; //signed
reg [31:0] reg1; //signed
reg [31:0] reg2; //signed
reg [31:0] reg3; //signed
reg B;
reg [19:0] MAR;
reg [31:0] MBR; //signed
reg [1:0] mf;
reg [2:0] df;
reg cf;
reg [3:0] ff;
reg [19:0] tail;
reg [31:0] IR; //signed
reg state;
reg [31:0] r,m,t; //signed
reg [31:0] d; //signed
reg [31:0] temp; //signed
reg [1:0] s;
reg [32:0] a; //signed
parameter FETCH=0, EXEC=1;
/////
always @(posedge clock)
begin
  if (reset)
  begin
      MAR = 0;
      MBR = 0;
      IR = 0;
      d = 0;
      r = 0;
      m = 0;
      s = 0;
      temp = 0;
      mf = 0;
      df = 0;
      ff = 0;
      cf = 0;
      tail = 0;
      B = 0;
      reg0 = 0;
      reg1 = 0;
      reg2 = 0;
      reg3 = 0;
      addr <= 0;
      rd <= 0;
      wr <= 0;
      datao <= 0;
      state = FETCH;
  end
  else
  begin
      rd <= 0;
      wr <= 0;
      case (state)
      FETCH:
      begin
        MAR = reg3 & 20'hfffff;
	addr <= MAR;
	rd <= 1;
	MBR = datai;
        IR = MBR;
	state = EXEC;
      end
      EXEC:
      begin
	if (IR[31]) //<0
	  IR = -IR;
	mf = (IR >> 27) & 3 ;
	df = (IR >> 24) & 7;
	ff = (IR >> 19) & 15;
	cf = (IR >> 23) & 1;
	tail = IR & 20'hfffff;
        reg3 = ((reg3 & 32'h1fffffff)- 8);  //rev
	s = (IR >> 29) & 3;
	case (s)
	0: r = reg0;
	1: r = reg1;
	2: r = reg2;
	3: r = reg3;
	endcase
	case (cf)
	1:
        begin
	  case (mf)
	  0:   m = tail;
	  1: begin
               m = datai;
	       addr <= tail;
	       rd <= 1;
             end
	  2: begin
               addr <= (tail - reg1) & 20'hfffff;  //rev
	       rd <= 1;
               m = datai;
             end
	  3: begin
               addr <= (tail - reg2) & 20'hfffff;  //rev
	       rd <= 1;
               m = datai;
             end
	  endcase
	  case (ff)
	  0: begin
	       a = {r[31],r} - {m[31],m};
	       if (a[32]) B = 1; //r<m
               else	  B = 0;
	     end
	  1: begin
	       a = {r[31],r} - {m[31],m};
	       if (!a[32]) B = 1; //not(r<m)
               else	   B = 0;
	     end
	  2: if (r == m) B = 1;
             else	  B = 0; 
	  3: if (r != m) B = 1;
             else	  B = 0; 
	  4: begin
	       a = {m[31],m} - {r[31],r};
	       if (!a[32]) B = 1; //not(m<r)
               else	   B = 0;
	     end
	  5: begin
	       a = {m[31],m} - {r[31],r};
	       if (a[32]) B = 1; //m<r
               else	  B = 0;
	     end
	  6: begin
	       if (!r[31] && r>32'h3fffffff) r = r - 32'h40000000;
	       a = {r[31],r} - {m[31],m};
	       if (a[32]) B = 1; //r<m
               else	  B = 0;
	     end 
	  7: begin
	       if (!r[31] && r>32'h3fffffff) r = r - 32'h40000000;
	       a = {r[31],r} - {m[31],m};
	       if (!a[32]) B = 1; //not(r<m)
               else	   B = 0;
	     end 
	  8: begin
	       a = {r[31],r} - {m[31],m};
	       if (a[32] || B) B = 1; //r<m
               else	       B = 0;
	     end 
	  9: begin
	       a = {r[31],r} - {m[31],m};
	       if (!a[32] || B) B = 1; //not(r<m)
               else	        B = 0;
	     end 
	  10: if (r == m || B) B = 1;
              else		B = 0;
	  11: if (r != m || B) B = 1;
              else	 	   B = 0;
	  12: begin
	        a = {m[31],m} - {r[31],r};
	        if (!a[32] || B) B = 1; //not(m<r)
                else	         B = 0;
	      end
	  13: begin
	        a = {m[31],m} - {r[31],r};
	        if (a[32] || B) B = 1; //m<r
                else	        B = 0;
	      end
	  14: begin
	       if (!r[31] && r>32'h3fffffff) r = r - 32'h40000000;
	       a = {r[31],r} - {m[31],m};
	       if (a[32] || B) B = 1; //r<m
               else	       B = 0;
	      end 
	  15: begin
	       if (!r[31] && r>32'h3fffffff) r = r - 32'h40000000;
	       a = {r[31],r} - {m[31],m};
	       if (!a[32] || B) B = 1; //not(r<m)
               else	        B = 0;
	      end 
	  endcase
	end
	0:
	begin
	  if (df != 7)
	  begin
	    if (df == 5)
	    begin
	         if (!B) d = 3;
	    end
	    else if (df == 4)
	    begin
	         if (B) d = 3;
	    end
	    else if (df == 3) d = 3;
	    else if (df == 2) d = 2;
	    else if (df == 1) d = 1;
	    else if (df == 0) d = 0;

	    case (ff)
	    0:
	    begin
	      case (mf)
	      0:   m = tail;
	      1: begin
		   m = datai;
		   addr <= tail;
		   rd <= 1;
		 end
	      2: begin
		  addr <= (tail - reg1) & 20'hfffff;  //rev
		  rd <= 1;
                  m = datai;
		 end
	      3: begin
		  addr <= (tail - reg2) & 20'hfffff;  //rev
		  rd <= 1;
                  m = datai;
		 end
	      endcase
	      t = 0;
	      case (d)
	      0: reg0 = t + m; //rev
	      1: reg1 = t + m; //rev
	      2: reg2 = t + m; //rev
	      3: reg3 = t + m; //rev
	      endcase
	    end
	    1:
	    begin
	      case (mf)
	      0:   m = tail;
	      1: begin
		   m = datai;
		   addr <= tail;
		   rd <= 1;
		 end
	      2: begin
		   addr <= (tail - reg1) & 20'hfffff; //rev
		   rd <= 1;
                   m = datai;
		 end
	      3: begin
		   addr <= (tail - reg2) & 20'hfffff; //rev
		   rd <= 1;
                   m = datai;
		 end
	      endcase
	      reg2 = reg3; 
	      reg3 = m;
	    end
	    2:
	    begin
	      case (mf)
	      0:   m = tail;
	      1: begin
		   m = datai;
		   addr <= tail;
		   rd <= 1;
		 end
	      2: begin
		   addr <= (tail - reg1) & 20'hfffff; //rev
		   rd <= 1;
                   m = datai;
		 end
	      3: begin
		   addr <= (tail - reg2) & 20'hfffff; //rev
		   rd <= 1;
                   m = datai;
		 end
	      endcase
	      case (d)
	      0: reg0 = m;
	      1: reg1 = m;
	      2: reg2 = m;
	      3: reg3 = m;
	      endcase
	    end
	    3:
	    begin 
	      case (mf)
	      0:  m = tail;
	      1: begin
		  m = datai;
		  addr <= tail;
		  rd <= 1;
		 end
	      2: begin
		   addr <= (tail - reg1) & 20'hfffff; //rev
		   rd <= 1;
                   m = datai;
		 end
	      3: begin
		   addr <= (tail - reg2) & 20'hfffff; //rev
		   rd <= 1;
                   m = datai;
		 end
	      endcase
	      case (d)
	      0: reg0 = m;
	      1: reg1 = m;
	      2: reg2 = m;
	      3: reg3 = m;
	      endcase
	    end
	    4:
	    begin
	      case (mf)
	      0: m = tail;
	      1: begin
		   m = datai;
		   addr <= tail;
		   rd <= 1;
		 end
	      2: begin
		   addr <= (tail - reg1) & 20'hfffff; //rev
		   rd <= 1;
                   m = datai;
		 end
	      3: begin
		   addr <= (tail - reg2) & 20'hfffff; //rev
		   rd <= 1;
                   m = datai;
		 end
	      endcase
	      case (d)
	      0: reg0 = (r - m) & 32'h3fffffff; //rev
	      1: reg1 = (r - m) & 32'h3fffffff; //rev
	      2: reg2 = (r - m) & 32'h3fffffff; //rev
	      3: reg3 = (r - m) & 32'h3fffffff; //rev
	      endcase
	    end
	    5:
	    begin
	      case (mf)
	      0:   m = tail;
	      1: begin
		   m = datai;
		   addr <= tail;
		   rd <= 1;
		 end
	      2: begin
		   addr <= (tail - reg1) & 20'hfffff; //rev
		   rd <= 1;
                   m = datai;
		 end
	      3: begin
		   addr <= (tail - reg2) & 20'hfffff; //rev
		   rd <= 1;
                   m = datai;
		 end
	      endcase
	      case (d)
	      0: reg0 = (r - m) & 32'h3fffffff; //rev
	      1: reg1 = (r - m) & 32'h3fffffff; //rev
	      2: reg2 = (r - m) & 32'h3fffffff; //rev
	      3: reg3 = (r - m) & 32'h3fffffff; //rev
	      endcase
	    end
	    6:
	    begin
	      case (mf)
	      0:   m = tail;
	      1: begin
		   m = datai;
		   addr <= tail;
		   rd <= 1;
		 end
	      2: begin
		   addr <= (tail - reg1) & 20'hfffff; //rev
		   rd <= 1;
                   m = datai;
		 end
	      3: begin
		   addr <= (tail - reg2) & 20'hfffff; //rev
		   rd <= 1;
                   m = datai;
		 end
	      endcase
	      case (d)
	      0: reg0 = (r + m) & 32'h3fffffff; //rev
	      1: reg1 = (r + m) & 32'h3fffffff; //rev
	      2: reg2 = (r + m) & 32'h3fffffff; //rev
	      3: reg3 = (r + m) & 32'h3fffffff; //rev
	      endcase
	    end
	    7:
	    begin
	      case (mf)
	      0:   m = tail;
	      1: begin
		   m = datai;
		   addr <= tail;
		   rd <= 1;
		 end
	      2: begin
		   addr <= (tail - reg1) & 20'hfffff; //rev
		   rd <= 1;
                   m = datai;
		 end
	      3: begin
		   addr <= (tail - reg2) & 20'hfffff; //rev
		   rd <= 1;
                   m = datai;
		 end
	      endcase
	      case (d)
	      0: reg0 = (r + m) & 32'h3fffffff; //rev
	      1: reg1 = (r + m) & 32'h3fffffff; //rev
	      2: reg2 = (r + m) & 32'h3fffffff; //rev
	      3: reg3 = (r + m) & 32'h3fffffff; //rev
	      endcase
	    end
	    8:
	    begin
	      case (mf)
	      0:   m = tail;
	      1: begin
		   m = datai;
		   addr <= tail;
		   rd <= 1;
		 end
	      2: begin
		   addr <= (tail - reg1) & 20'hfffff; //rev
		   rd <= 1;
                   m = datai;
		 end
	      3: begin
		   addr <= (tail - reg2) & 20'hfffff; //rev
		   rd <= 1;
                   m = datai;
		 end
	      endcase
	      case (d)
	      0: reg0 = (r - m) & 32'h3fffffff; //rev
	      1: reg1 = (r - m) & 32'h3fffffff; //rev
	      2: reg2 = (r - m) & 32'h3fffffff; //rev
	      3: reg3 = (r - m) & 32'h3fffffff; //rev
	      endcase
	    end
	    9:
	    begin
	      case (mf)
	      0:   m = tail;
	      1: begin
		   m = datai;
		   addr <= tail;
		   rd <= 1;
		 end
	      2: begin
		   addr <= (tail - reg1) & 20'hfffff; //rev
		   rd <= 1;
                   m = datai;
		 end
	      3: begin
		   addr <= (tail - reg2) & 20'hfffff; //rev
		   rd <= 1;
                   m = datai;
		 end
	      endcase
	      case (d)
	      0: reg0 = (r + m) & 32'h3fffffff; //rev
	      1: reg1 = (r + m) & 32'h3fffffff; //rev
	      2: reg2 = (r + m) & 32'h3fffffff; //rev
	      3: reg3 = (r + m) & 32'h3fffffff; //rev
	      endcase
	    end
	    10: 
	    begin
	      case (mf)
	      0:   m = tail;
	      1: begin
		   m = datai;
		   addr <= tail;
		   rd <= 1;
		 end
	      2: begin
		   addr <= (tail - reg1) & 20'hfffff; //rev
		   rd <= 1;
                   m = datai;
		 end
	      3: begin
		   addr <= (tail - reg2) & 20'hfffff; //rev
		   rd <= 1;
                   m = datai;
		 end
	      endcase
	      case (d)
	      0: reg0 = (r - m) & 32'h3fffffff; //rev
	      1: reg1 = (r - m) & 32'h3fffffff; //rev
	      2: reg2 = (r - m) & 32'h3fffffff; //rev
	      3: reg3 = (r - m) & 32'h3fffffff; //rev
	      endcase
	    end
	    11:
	    begin
	      case (mf)
	      0:   m = tail;
	      1: begin
		   m = datai;
		   addr <= tail;
		   rd <= 1;
		 end
	      2: begin
		   addr <= (tail - reg1) & 20'hfffff; //rev
		   rd <= 1;
                   m = datai;
		 end
	      3: begin
		   addr <= (tail - reg2) & 20'hfffff; //rev
		   rd <= 1;
                   m = datai;
		 end
	      endcase
	      case (d)
	      0: reg0 = (r + m) & 32'h3fffffff; //rev
	      1: reg1 = (r + m) & 32'h3fffffff; //rev
	      2: reg2 = (r + m) & 32'h3fffffff; //rev
	      3: reg3 = (r + m) & 32'h3fffffff; //rev
	      endcase
	    end
	    12:
	    begin
	      case (mf) //rev
	      0:   if (r[31]) t = -(-r >> 1);
		   else       t = r >> 1;
              3: begin
		   if (r[31]) t = -(-r >> 1);
		   else       t = r >> 1;
		   if (B) t = t & 32'h1fffffff;
		 end
	      1: t = (r & 32'h1fffffff) << 1;
	      2: begin
		   t = (r & 32'h1fffffff) << 1;
		   if (!t[31] && t > 32'h3fffffff) B = 1;
		   else			           B = 0;
		 end
	      endcase
	      case (d)
	      0: reg0 = t;
	      1: reg1 = t;
	      2: reg2 = t;
	      3: reg3 = t;
	      endcase
	    end
	    endcase
	  end
	  else
	  begin
	    if (df == 7)
	    begin
	      case (mf) //rev
	      3: m = tail;
	      2: m = tail;
	      0: m = (reg1 & 20'hfffff) - (tail & 20'hfffff);
	      1: m = (reg2 & 20'hfffff) - (tail & 20'hfffff);
	      endcase
	      addr <= m & 20'hfffff;
	      wr <=1;
	      datao <= r;
	    end
	  end
	end
	endcase
	state = FETCH;
      end
      endcase
  end
end
endmodule

//////////

module b20 (clock, reset, si, rd, wr, so);
input clock;
input reset;
input [31:0] si; // signed
output rd;
output wr;
output [19:0] so;
/////
wire clock;
wire reset;
wire [31:0] si;
reg rd;
reg wr;
reg [19:0] so;
/////
wire [19:0] addr_1, addr_2;
wire [31:0] datao_1, datao_2;
wire rd_1, rd_2, wr_1, wr_2;
reg [31:0] datai_1,datai_2;
/////
b14  P1(clock, reset, datai_1, rd_1, wr_1, addr_1, datao_1);
b14rev  P2(clock, reset, datai_2, rd_2, wr_2, addr_2, datao_2);
/////
always @(addr_1 or addr_2 or rd_1 or rd_2 or wr_1 or wr_2 or datao_1 or datao_2 or si)
begin
    so <= (addr_1 + addr_2) & 20'hfffff;

    rd <= rd_1 ^ ~rd_2;
    wr <= wr_1 ^ ~wr_2;

    if ((addr_1 < 20'h80000 && addr_2 < 20'h80000 && !rd_1) ||
	(addr_1 > 20'h7ffff && addr_2 > 20'h7ffff && !rd_2))
    begin
	datai_1 <= datao_2 + si;
	datai_2 <= datao_1;
    end
    else
    begin
	datai_1 <= datao_2;
	datai_2 <= datao_1 + si;
    end
end
endmodule
